package com.och.mrcp.core.rtp.model;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.nio.ByteBuffer;

/**
 * RTP包模型
 * RFC 3550 - RTP: A Transport Protocol for Real-Time Applications
 */
@Data
@Slf4j
public class RtpPacket {
    
    // RTP头部字段
    private int version = 2;           // 版本号，固定为2
    private boolean padding = false;   // 填充标志
    private boolean extension = false; // 扩展标志
    private int csrcCount = 0;         // CSRC计数
    private boolean marker = false;    // 标记位
    private int payloadType = 8;       // 负载类型 (8=PCMA, 0=PCMU)
    private int sequenceNumber;        // 序列号
    private long timestamp;            // 时间戳
    private int ssrc;                  // 同步源标识符
    private int[] csrcList;            // CSRC列表
    
    // 扩展头部
    private boolean hasExtension = false;
    private int extensionProfile;
    private byte[] extensionData;
    
    // 负载数据
    private byte[] payload;
    
    // 原始数据
    private byte[] rawData;
    
    // 到达时间（毫秒）用于抖动缓冲区过期判断
    private long arrivalTimeMs;
    
    // RFC 3550 Section 5.1 - 常量定义
    public static final int RTP_VERSION = 2;
    public static final int MAX_CSRC_COUNT = 15;
    public static final int MIN_HEADER_SIZE = 12;
    public static final int MAX_PAYLOAD_TYPE = 127;
    public static final int MAX_SEQUENCE_NUMBER = 65535;
    
    public RtpPacket() {
        this.csrcList = new int[MAX_CSRC_COUNT]; // 最多15个CSRC (RFC 3550 Section 5.1)
    }
    
    /**
     * 从字节数组解析RTP包 (RFC 3550 Section 5.1)
     */
    public static RtpPacket parse(byte[] data) {
        if (data == null || data.length < MIN_HEADER_SIZE) {
            throw new IllegalArgumentException("RTP packet too short: " + (data != null ? data.length : 0));
        }
        
        RtpPacket packet = new RtpPacket();
        packet.rawData = data;
        packet.arrivalTimeMs = System.currentTimeMillis();
        
        ByteBuffer buffer = ByteBuffer.wrap(data);
        
        // 第一个字节：版本、填充、扩展、CSRC计数 (RFC 3550 Section 5.1)
        byte firstByte = buffer.get();
        packet.version = (firstByte >> 6) & 0x03;
        packet.padding = ((firstByte >> 5) & 0x01) == 1;
        packet.extension = ((firstByte >> 4) & 0x01) == 1;
        packet.csrcCount = firstByte & 0x0F;
        
        // 验证版本号 (RFC 3550 Section 5.1)
        if (packet.version != RTP_VERSION) {
            throw new IllegalArgumentException("Invalid RTP version: " + packet.version);
        }
        
        // 验证CSRC计数 (RFC 3550 Section 5.1)
        if (packet.csrcCount > MAX_CSRC_COUNT) {
            throw new IllegalArgumentException("Invalid CSRC count: " + packet.csrcCount);
        }
        
        // 第二个字节：标记、负载类型 (RFC 3550 Section 5.1)
        byte secondByte = buffer.get();
        packet.marker = ((secondByte >> 7) & 0x01) == 1;
        packet.payloadType = secondByte & 0x7F;
        
        // 验证负载类型 (RFC 3550 Section 5.1)
        if (packet.payloadType > MAX_PAYLOAD_TYPE) {
            throw new IllegalArgumentException("Invalid payload type: " + packet.payloadType);
        }
        
        // 序列号 (16位) (RFC 3550 Section 5.1)
        packet.sequenceNumber = buffer.getShort() & 0xFFFF;
        
        // 时间戳 (32位) (RFC 3550 Section 5.1)
        packet.timestamp = buffer.getInt() & 0xFFFFFFFFL;
        
        // SSRC (32位) (RFC 3550 Section 5.1)
        packet.ssrc = buffer.getInt();
        
        // CSRC列表 (RFC 3550 Section 5.1)
        for (int i = 0; i < packet.csrcCount; i++) {
            if (buffer.remaining() >= 4) {
                packet.csrcList[i] = buffer.getInt();
            } else {
                log.warn("Insufficient data for CSRC list, expected {} but got {}", 
                        packet.csrcCount * 4, buffer.remaining());
                break;
            }
        }
        
        // 扩展头部 (RFC 3550 Section 5.3.1)
        if (packet.extension && buffer.remaining() >= 4) {
            packet.hasExtension = true;
            packet.extensionProfile = buffer.getShort() & 0xFFFF;
            int extensionLength = buffer.getShort() & 0xFFFF;
            
            if (buffer.remaining() >= extensionLength * 4) {
                packet.extensionData = new byte[extensionLength * 4];
                buffer.get(packet.extensionData);
            } else {
                log.warn("Insufficient data for extension header, expected {} but got {}", 
                        extensionLength * 4, buffer.remaining());
            }
        }
        
        // 负载数据 (RFC 3550 Section 5.1)
        int payloadOffset = MIN_HEADER_SIZE + (packet.csrcCount * 4);
        if (packet.hasExtension && packet.extensionData != null) {
            payloadOffset += 4 + packet.extensionData.length;
        }
        
        if (data.length > payloadOffset) {
            packet.payload = new byte[data.length - payloadOffset];
            System.arraycopy(data, payloadOffset, packet.payload, 0, packet.payload.length);
        }
        
        return packet;
    }
    
    /**
     * 将RTP包编码为字节数组 (RFC 3550 Section 5.1)
     */
    public byte[] encode() {
        // 计算头部大小
        int headerSize = MIN_HEADER_SIZE + (csrcCount * 4);
        if (hasExtension && extensionData != null) {
            headerSize += 4 + extensionData.length;
        }
        
        // 计算总大小
        int totalSize = headerSize + (payload != null ? payload.length : 0);
        ByteBuffer buffer = ByteBuffer.allocate(totalSize);
        
        // 第一个字节 (RFC 3550 Section 5.1)
        byte firstByte = (byte) ((version << 6) | (padding ? 0x20 : 0) | (extension ? 0x10 : 0) | csrcCount);
        buffer.put(firstByte);
        
        // 第二个字节 (RFC 3550 Section 5.1)
        byte secondByte = (byte) ((marker ? 0x80 : 0) | payloadType);
        buffer.put(secondByte);
        
        // 序列号 (RFC 3550 Section 5.1)
        buffer.putShort((short) sequenceNumber);
        
        // 时间戳 (RFC 3550 Section 5.1)
        buffer.putInt((int) timestamp);
        
        // SSRC (RFC 3550 Section 5.1)
        buffer.putInt(ssrc);
        
        // CSRC列表 (RFC 3550 Section 5.1)
        for (int i = 0; i < csrcCount; i++) {
            buffer.putInt(csrcList[i]);
        }
        
        // 扩展头部 (RFC 3550 Section 5.3.1)
        if (hasExtension && extensionData != null) {
            buffer.putShort((short) extensionProfile);
            buffer.putShort((short) (extensionData.length / 4));
            buffer.put(extensionData);
        }
        
        // 负载数据 (RFC 3550 Section 5.1)
        if (payload != null) {
            buffer.put(payload);
        }
        
        return buffer.array();
    }
    
    /**
     * 检查RTP包是否有效 (RFC 3550 Section 5.1)
     */
    public boolean isValid() {
        return version == RTP_VERSION && 
               csrcCount >= 0 && csrcCount <= MAX_CSRC_COUNT &&
               payloadType >= 0 && payloadType <= MAX_PAYLOAD_TYPE &&
               sequenceNumber >= 0 && sequenceNumber <= MAX_SEQUENCE_NUMBER &&
               ssrc != 0; // SSRC不能为0 (RFC 3550 Section 8.1)
    }
    
    /**
     * 获取负载大小
     */
    public int getPayloadSize() {
        return payload != null ? payload.length : 0;
    }
    
    /**
     * 获取包的总大小
     */
    public int getPacketSize() {
        return rawData != null ? rawData.length : encode().length;
    }
    
    /**
     * 获取头部大小
     */
    public int getHeaderSize() {
        int headerSize = MIN_HEADER_SIZE + (csrcCount * 4);
        if (hasExtension && extensionData != null) {
            headerSize += 4 + extensionData.length;
        }
        return headerSize;
    }
    
    /**
     * 检查是否为音频包
     */
    public boolean isAudioPacket() {
        // RFC 3551 - RTP Profile for Audio and Video Conferences
        return payloadType >= 0 && payloadType <= 23;
    }
    
    /**
     * 检查是否为视频包
     */
    public boolean isVideoPacket() {
        // RFC 3551 - RTP Profile for Audio and Video Conferences
        return payloadType >= 24 && payloadType <= 34;
    }
    
    /**
     * 获取负载类型描述
     */
    public String getPayloadTypeDescription() {
        switch (payloadType) {
            case 0: return "PCMU";
            case 8: return "PCMA";
            case 10: return "PCM";
            case 11: return "G.723";
            case 13: return "CN";
            case 16: return "G.728";
            case 18: return "G.729";
            case 26: return "JPEG";
            case 31: return "H.261";
            case 32: return "MPV";
            case 33: return "MP2T";
            case 34: return "H.263";
            default: return "Unknown(" + payloadType + ")";
        }
    }
    
    @Override
    public String toString() {
        return String.format("RtpPacket{version=%d, payloadType=%d(%s), seq=%d, timestamp=%d, ssrc=%d, payloadSize=%d, valid=%s}",
                version, payloadType, getPayloadTypeDescription(), sequenceNumber, timestamp, ssrc, getPayloadSize(), isValid());
    }
}
